#ifndef __AUDIO_ANALYSE_API_H__
#define __AUDIO_ANALYSE_API_H__

#include "Types.h"
#include "AudioIn.h"
#include "AudioEnc.h"

#ifdef __cplusplus
extern "C" {
#endif

/// \defgroup audioAnalyseAPI API Audio Analyser
/// 音频分析接口
///	\n 调用流程图:
/// \
///    ===========================
///				   |
///		   *createaudioAnalyser
///				   |
///				addRef
///				   |
///				getCaps
///				   |
///				setformat
///				   |
///				  start
///				   |\----------------+
///		   +------\|						 |
///		   |  getResult(releaseResult)	setRuleConfig
///		   +------/|						 |
///						 |/----------------+
///						 |
///					   stop
///						 |
///				release
///				   |
///    ===========================
/// \
/// @{


/// 音频分析服务类型
typedef enum AudioAnalyseServiceType
{
	AudioAnalyseServiceAQD	= 1 << 0,		///< AQD检测服务
} AudioAnalyseServiceType;

/// 音频警告类型
typedef enum AudioWarnType
{
	AudioNormal = 0,	/// 正常无报警
	AudioPowerWeak,		/// 声音太小或无声
	AudioLoudly,		/// 声音太大
	AudioNoise			/// 有噪音或杂音
} AudioWarnType;

/// 音频分析设备特性结构，128字节
typedef struct AudioAnalyseCaps
{
	uint	maxRules;			///< 一次设置的最大规则数
	uint	ruleTypeMask[8];	///< 支持的规则类型
	int		reserved[23];	///< 保留字节
} AudioAnalyseCaps;

/// 音频分析规则类型
typedef enum AudioAnalyseRuleType
{
	AudioAnalyseLoudly = 0, ///< 音量过高检测
	AudioAnalyseWeak,		///< 音量过低检测
	AudioAnalyseNoise		///< 音频杂音检测
} AudioAnalyseRuleType;

///音频分析规则产生的事件，128字节
typedef struct AudioAnalyseEvent
{
	uint					ruleId : 8;			///< 所属规则ID
	AudioAnalyseRuleType	ruleType : 8;		///< 规则类型
	uint					reservedBits : 16;	///< 保留位
	int						reserved[7];		///< 保留字节，保证非联合部分未32字节
	union
	{
		int placeholder[24]; ///< 占位符，保证这个联合体体为96字节
	}result;
}AudioAnalyseEvent;

/// 音频分析检测规则配置，128字节
typedef struct AudioAnalyseRuleConfig
{
	uint						id : 8;				///< 规则ID
	AudioAnalyseRuleType		ruleType : 8;		///< 规则类型
	uint						reservedBits : 16;	///< 保留位
	uint						reserved[7];		///< 保留字节，保证非联合体32字节
	union
	{
		struct AudioLoudly			///< 音量过高检测
		{
			int		dbUpLimit;		///< 音频分贝上限阈值，建议70-80之间
		} audioLoudly;

		struct AudioWeak			///< 音量过低检测
		{
			int		dbDownLimit;	///< 音频分贝下限阈值，建议0或者0以下且大于-80
		} audioWeak;

		int placeholder[24];		///< 占位符，保证这个联合体体为64字节
	} config;
}AudioAnalyseRuleConfig;

/// 音频分析数据格式结构, 64字节
typedef struct AudioAnalyseFormat
{
	int		numPerFrm;		///< 音频每帧采样点个数
	int		bitWidth;		///< 音频流数据位宽
	int		samplerate;		///< 音频流数据采样率
	int		channel;		///< 音频流数据通道数
	int 	reserved[12];	///< 保留字节
} AudioAnalyseFormat;

/// 音频分析包，128字节
typedef struct AudioAnalysePacket
{
	uint64				pts;			///< 时间戳，毫秒为单位
	ulong				sequence;		///< 帧序号，用于校验是否丢帧
	ulong				utc;			///< 对应的UT(1970-1-1 00:00:00)秒数
	uint				eventNumber;	///< 事件个数
	AudioAnalyseEvent	*events;		///< 事件列表
	int					reserved[27];	///< 保留字节
} AudioAnalysePacket;

/// 音频分析接口, 512字节
typedef struct AudioAnalyser
{
	/// 底层私有数据
	void *priv;

	/// 增加接口引用
	int (*addRef)(struct AudioAnalyser *thiz);

	/// 释放接口
	int (*release)(struct AudioAnalyser *thiz);

	/// 得到音频支持的特性
	int (*getCaps)(struct AudioAnalyser *thiz, AudioAnalyseCaps * caps);

	/// 开始分析
	///
	/// \param [in] thiz 音频分析接口指针
	/// \retval 0  开始成功
	/// \retval <0	开始失败
	int (*start)(struct AudioAnalyser *thiz);

	/// 停止分析
	///
	/// \param [in]  thiz 音频分析接口指针
	/// \retval 0  停止成功
	/// \retval <0	停止失败
	int (*stop)(struct AudioAnalyser *thiz);

	/// 获取音频分析结果
	///
	/// \param [in] thiz 音频分析接口指针
	/// \param [in] packet 音频分析结果
	/// \retval 0  获取成功
	/// \retval <0	获取失败
	int (*getPacket)(struct AudioAnalyser *thiz, AudioAnalysePacket *packet);

	///释放音频分析结果资源, 需要与getPacket成对调用
	///
	/// \param [in] thiz 音频分析接口指针
	/// \retval 0  释放成功
	/// \retval <0 释放失败
	int (*releasePacket)(struct AudioAnalyser *thiz);

	/// 设置音频分析规则配置
	///
	/// \param [in] thiz 音频分析接口指针
	/// \param [in] count 规则数目，每个分析器可以设置多个规则
	/// \param [in] config 视频分析规则配置结构AudioAnalyseRuleCfg指针
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setRuleConfig)(struct AudioAnalyser *thiz, int count, AudioAnalyseRuleConfig*config);

	/// 设置待分析的音频的流长度、位宽、采样率、通道等格式。
	///
	/// \param [in] thiz 音频分析接口指针
	/// \param [in] format 视频分析格式结构指针。
	/// \retval 0  设置成功
	/// \retval <0	设置失败
	int (*setFormat)(struct AudioAnalyser *thiz, AudioAnalyseFormat *format);

	///< 保留
	void* reserved[118];
} AudioAnalyser;

/// 得到音频分析最大通道的个数
int PAL_API getAudioAnalyseChannels();

/// 音频分析接口描述，64字节
typedef struct AudioAnalyseDesc
{
	int	channel;					///< 音频分析通道号
	unsigned int serviceTypeMask;	///< 智能算法服务类型掩码，由AudioAnalyseServiceType枚举掩码组成,支持多个算法同时开启
	int reserved[14];				///< 保留
} AudioAnalyseDesc;

/// 创建音频分析接口
///
/// \param [in] dest 音频分析接口描述结构AudioAnalyseDesc指针
/// \param [out] audioAnalyser 音频分析指针的指针
/// \retval <0 创建失败
/// \retval 0 创建成功
int PAL_API createAudioAnalyser(AudioAnalyseDesc *desc, AudioAnalyser **audioAnalyser);

#ifdef __cplusplus
}
#endif

#endif //__AUDIO_ANALYSE_API_H__

